<template>
  <div ref="terminal" style="height: 86vh; width: 100%;"></div>
</template>
<script>
import '@xterm/xterm/css/xterm.css'
import { Terminal } from 'xterm'
import { FitAddon } from '@xterm/addon-fit'
export default {
  name: 'Term',
  data() {
    return {
      term: null,
      ws: null,
      value: '',
      path: '/',
      link: ``,
      hostId:null
    }
  },
  mounted() {
  },
  deactivated() {
    this.term.dispose()
    this.ws.close()
  },
  activated() {
    const { data } = this.$route.query
    this.hostId = data.id
    let protocol = 'ws://'
    if (window.location.protocol == 'https:') {
      protocol = 'wss://';
    } else {
      protocol = 'ws://';
    }
    this.link = `${protocol}119.29.188.22:8080/wsh?hostId=${this.hostId}&serialNum=${data.serialNum}`
    this.initSocket()
  },
  methods: {
    initTerm() {
      const term = new Terminal({
        rendererType: 'canvas',
        rows: 10,
        convertEol: true,
        disableStdin: false,
        windowsMode: true,
        cursorStyle: 'underline',
        cursorBlink: true,
        scrollbar: {
          visible: false
        },
        theme: {
          cursor: 'help',
          lineHeight: 20,
          fontSize: '16px',
          foreground: '#ebeef5',
          background: '#1d2935'
        }
      })
      term.onData((val) => {
        if (val !== '\r') {
          this.value += val
          term.write(val)
        } else {
          const params = {
            // currentPath: this.path,
            command: this.value,
            operate: 'connect',
            hostId: this.hostId
          }
          this.ws.send(JSON.stringify(params))
          this.value = ''
        }
      })
      term.onKey((val) => {
        const code = val.domEvent.keyCode
        if (code === 13) {
          if (this.value.includes('clear')) {
            term.reset()
            term.writeln(' Hello Docker Insight ')
          }
          term.write(val.key + '\n# ')
        } else if (code === 8) {
          if (term._core.buffer.x > 2) {
            term.write('\b \b')
            const v = term._core.element.innerText.split('#')
            this.value = v.at(-1).trim()
            this.value = this.value.slice(0, this.value.length - 1)
          }
        } else if (code === 46) {
          if (term._core.buffer.x > 2) {
            term.write(' \b')
          }
        } else if (code === 40 || code === 38) {
          return 'IDisposable'
        }
      })
      const fitAddon = new FitAddon()
      term.loadAddon(fitAddon)
      term.open(this.$refs.terminal)
      term.focus()
      term.writeln(' Hello Docker Insight ')
      term.writeln('')
      term.write('# ')
      fitAddon.fit()
      term.focus()
      this.term = term
    },
    initSocket() {
      this.ws = new WebSocket(this.link)
      this.socketOnOpen()
      this.socketOnMsg()
      this.socketOnError()
      this.socketOnClose()
    },
    socketOnOpen() {
      this.ws.onopen = (e) => {
        this.initTerm()
      }
    },
    socketOnError() {
      this.ws.onerror = (e) => {
        this.$message.error(`连接失败, ${e.target.url}`)
      }
    },
    socketOnClose() {
      this.ws.onclose = () => {
      }
    },
    socketOnMsg() {
      this.ws.onmessage = (e) => {
        const { data } = e
        if (data.includes('终端连接成功')) {
          this.term.writeln(data)
          this.term.write('# ')
        } else if (data.includes('result')) {
          const val = JSON.parse(data)
          this.path = val.currentPath
          if (val.result.length > 0) {
            this.term.writeln(val.result)
            this.term.write('# ')
          }
        } else if (this.value.includes('clear')) {
          this.term.reset()
          this.value = ''
          this.term.writeln(' Hello Docker Insight ')
          this.term.writeln('')
          this.term.write('# ')
        } else if (this.value === '\x7F') {
        } else {
          this.term.writeln(`${this.value}: command not found`)
          this.term.write('# ')
        }
        this.value = ''
      }
    }
  }
}
</script>
<style lang="less" scoped>
::v-deep .xterm-viewport {
  height: 100%;
  overflow: auto;
  border: 1px solid green;

  &::-webkit-scrollbar {
    display: none;
  }
}

::v-deep .xterm-rows {
  padding: 10px;
  height: 100%;
  width: 100%;
  overflow: auto;

  &::-webkit-scrollbar {
    display: none;
  }

  div {
    margin: 5px 0;
  }

}
</style>
